<!--
 * @Descripttion: ice
 * @version: 1.0.0
 * @Author: ice
 * @Date: 2025-02-25 11:47:52
 * @LastEditors: ice
 * @LastEditTime: 2025-02-25 11:48:35
-->
<template>
    <div>
        <h2>日志审计</h2>
        <el-tabs type="border-card">
            <el-tab-pane label="事件日志">事件日志</el-tab-pane>
            <el-tab-pane label="流量日志">
                <div v-if="vueChange">
                    <div class="file-list-container">

                        <div class="block">
                            <span class="demonstration"></span>
                            <el-date-picker v-model="value2" type="datetimerange" :picker-options="pickerOptions"
                                range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" align="right">
                            </el-date-picker>
                        </div>

                        <el-table :data="paginatedFiles" stripe empty-text="暂无日志文件" class="log-table">
                            <el-table-column prop="name" label="文件名" sortable min-width="300">
                                <template #default="{ row }">
                                    <div class="file-name-cell">
                                        <i class="el-icon-document"></i>
                                        <span class="text">{{ row }}</span>
                                    </div>
                                </template>
                            </el-table-column>
                            <el-table-column label="操作" width="120" align="right">
                                <template #default="{ row }">
                                    <el-button type="primary" size="mini" @click.stop="getLogs(row)">
                                        查看
                                    </el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </div>
                    <!-- 分页组件 -->
                    <div class="pagination-container">
                        <el-pagination background layout="total, sizes, prev, pager, next" :total="filteredFileNames.length"
                            v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100]"
                            @current-change="handlePageChange" @size-change="handlePageSizeChange"
                            @prev-click="handlePrevClick" @next-click="handleNextClick" />
                    </div>
                </div>
                <!-- <LogsData v-else></LogsData> -->

                <div v-else>
                    <div class="top">
                        <h2>日志详情</h2>
                        <el-button @click="vueChange = true" type="info" plain style="height: 40px;">返回</el-button>
                    </div>

                    <div class="search">
                        <el-select v-model="packetsSearch.protocolValue" placeholder="请选择">
                            <el-option v-for="item in protocolOptions" :key="item.value" :label="item.label"
                                :value="item.value">
                            </el-option>
                        </el-select>
                        <el-select v-model="packetsSearch.dataProtocol" placeholder="请选择">
                            <el-option v-for="item in dataProtocolOptions" :key="item.value" :label="item.label"
                                :value="item.value">
                            </el-option>
                        </el-select>
                        <el-input v-model="packetsSearch.src" placeholder="请输入源地址"></el-input>
                        <el-input v-model="packetsSearch.dst" placeholder="请输入目的地址"></el-input>
                        <el-input v-model="packetsSearch.srcPort" placeholder="请输入源端口"></el-input>
                        <el-input v-model="packetsSearch.dstPort" placeholder="请输入目的端口"></el-input>
                        <el-button @click="searchLogs" type="primary" plain style="height: 40px;">搜索</el-button>
                        <el-button @click="resetLogs" type="warning" plain style="height: 40px;">重置</el-button>
                        <!-- {{ logData }} -->
                    </div>
                    <div>
                        <el-table :data="listPaginatedFiles" style="width: 100%">
                            <el-table-column prop="timestamp" label="时间戳"></el-table-column>
                            <el-table-column prop="ethSrc" label="以太网源地址"></el-table-column>
                            <el-table-column prop="ethDst" label="以太网目的地址"></el-table-column>
                            <el-table-column prop="ipv4Src" label="IPv4 源地址"></el-table-column>
                            <el-table-column prop="ipv4Dst" label="IPv4 目的地址"></el-table-column>
                            <el-table-column prop="ipv6Src" label="IPv6 源地址"></el-table-column>
                            <el-table-column prop="ipv6Dst" label="IPv6 目的地址"></el-table-column>
                            <el-table-column prop="protocol" label="协议"></el-table-column>
                            <el-table-column prop="dataProtocol" label="数据协议"></el-table-column>
                            <el-table-column prop="udpSrcPort" label="UDP 源端口"></el-table-column>
                            <el-table-column prop="udpDstPort" label="UDP 目的端口"></el-table-column>
                            <el-table-column prop="tcpSrcPort" label="TCP 源端口"></el-table-column>
                            <el-table-column prop="tcpDstPort" label="TCP 目的端口"></el-table-column>
                        </el-table>
                    </div>
                    <!-- 分页组件 -->
                    <div class="pagination-container">
                        <el-pagination background layout="total, sizes, prev, pager, next" :total="listSum"
                            v-model:current-page="listcurrentPage" v-model:page-size="listpageSize"
                            :page-sizes="[10, 20, 50, 100]" @current-change="listhandlePageChange"
                            @size-change="listhandlePageSizeChange" @prev-click="listhandlePrevClick"
                            @next-click="listhandleNextClick" />
                    </div>
                </div>
            </el-tab-pane>
            <el-tab-pane label="操作日志">操作日志</el-tab-pane>
        </el-tabs>
    </div>
</template>

<script>
import { getLogsName, getLogsList } from '@/api/logs/logs'
export default {
    data() {
        return {
            logData: [
                {
                    timestamp: '2025-02-21T17:59:05.000+08:00',
                    ethSrc: '14:5a:fc:23:d8:89',
                    ethDst: '16:ea:04:9d:4a:17',
                    ipv4Src: '192.168.153.238',
                    ipv4Dst: '47.109.85.30',
                    ipv6Src: 'null',
                    ipv6Dst: 'null',
                    protocol: 'IPv4',
                    dataProtocol: 'TCP',
                    udpSrcPort: '-1',
                    udpDstPort: '-1',
                    tcpSrcPort: '51447',
                    tcpDstPort: '22',
                    data: null
                },
                {
                    timestamp: '2025-02-21T17:59:05.000+08:00',
                    ethSrc: '16:ea:04:9d:4a:17',
                    ethDst: '14:5a:fc:23:d8:89',
                    ipv4Src: '119.36.154.69',
                    ipv4Dst: '192.168.153.238',
                    ipv6Src: 'null',
                    ipv6Dst: 'null',
                    protocol: 'IPv4',
                    dataProtocol: 'TCP',
                    udpSrcPort: '-1',
                    udpDstPort: '-1',
                    tcpSrcPort: '16617',
                    tcpDstPort: '51446',
                    data: null
                }
            ],
            searchData: [
            ],

            pickerOptions: {
                shortcuts: [{
                    text: '最近一周',
                    onClick(picker) {
                        const end = new Date();
                        const start = new Date();
                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
                        picker.$emit('pick', [start, end]);
                    }
                }]
            },
            value1: [new Date(2000, 10, 10, 10, 10), new Date(2000, 10, 11, 10, 10)],
            value2: '', // 时间选择器的值
            fileNames: [], // 所有文件名
            filteredFileNames: [], // 筛选后的文件名
            currentPage: 1,
            pageSize: 10,

            listSum: 0,
            listcurrentPage: 1,
            listpageSize: 10,

            vueChange: true,
            protocolOptions: [{
                value: 'IPv4',
                label: 'IPv4'
            }, {
                value: 'IPv6',
                label: 'IPv6'
            }],
            dataProtocolOptions: [{
                value: 'TCP',
                label: 'TCP'
            }, {
                value: 'UDP',
                label: 'UDP'
            }],
            packetsSearch: {
                protocolValue: 'IPv4',
                dataProtocol: 'TCP',
                src: '',
                dst: '',
                srcPort: '',
                dstPort: ''
            }
        }
    },
    computed: {
        // 修改后的计算属性，返回筛选后的文件列表
        paginatedFiles() {
            const sorted = [...this.filteredFileNames].sort((a, b) => b.localeCompare(a))
            return sorted.slice(
                (this.currentPage - 1) * this.pageSize,
                this.currentPage * this.pageSize
            )
        },
        listPaginatedFiles() {
            // 防御式编程：确保数据源稳定性 
            const validData = Array.isArray(this.searchData) ? [...this.searchData] : []

            // 智能排序：基于时间戳的精准排序（支持ISO 8601格式）
            const sorted = validData.sort((a, b) => {
                // 异常数据处理 
                const timeA = a.timestamp?.replace(/,$/, '') || '1970-01-01T00:00:00.000Z'
                const timeB = b.timestamp?.replace(/,$/, '') || '1970-01-01T00:00:00.000Z'

                // 支持跨时区比较（自动处理+08:00时区标识）
                return new Date(timeB) - new Date(timeA)
            })

            // 分页安全计算（防止负值溢出）
            const startIndex = Math.max(0, (this.listcurrentPage - 1) * this.listpageSize)
            const endIndex = Math.min(startIndex + this.listpageSize, validData.length)

            // 返回不可变数据副本 
            return Object.freeze(sorted.slice(startIndex, endIndex))
        }
    },
    watch: {
        $route() {
            this.currentPage = 1
        },
        // 监听时间选择器的变化，进行筛选
        value2(newVal) {
            if (newVal && newVal.length === 2) {
                const [start, end] = newVal;
                this.filteredFileNames = this.fileNames.filter(fileName => {
                    const dateStr = fileName.split('_')[0] + 'T' + fileName.split('_')[1].replace(/-/g, ':');
                    const fileDate = new Date(dateStr);
                    return fileDate >= start && fileDate <= end;
                });
            } else {
                this.filteredFileNames = this.fileNames;
            }
            this.currentPage = 1; // 重置到第一页
        }
    },
    methods: {
        // 获取文件名列表
        getLogsName() {
            getLogsName().then((response) => {
                this.fileNames = response;
                this.filteredFileNames = response; // 初始化筛选后的文件列表
            })
        },
        // 下一页
        handleNextClick() {
            if (this.currentPage === Math.ceil(this.fileNames.length / this.pageSize)) return
            this.currentPage++
        },
        // 上一页
        handlePrevClick() {
            if (this.currentPage === 1) return
            this.currentPage--
        },
        // 页码改变事件
        handlePageChange(newPage) {
            this.currentPage = newPage
            this.scrollToTop()
        },

        // 每页条数改变事件
        handlePageSizeChange(newSize) {
            this.pageSize = newSize
            this.currentPage = 1 // 重置到第一页
            this.scrollToTop()
        },


        // 下一页
        listhandleNextClick() {
            if (this.listcurrentPage === Math.ceil(this.logData.length / this.listpageSize)) return
            this.listcurrentPage++
        },
        // 上一页
        listhandlePrevClick() {
            if (this.listcurrentPage === 1) return
            this.listcurrentPage--
        },
        // 页码改变事件
        listhandlePageChange(newPage) {
            this.listcurrentPage = newPage
        },

        // 每页条数改变事件
        listhandlePageSizeChange(newSize) {
            this.listpageSize = newSize
            this.listcurrentPage = 1 // 重置到第一页
        },



        // 公共滚动方法
        scrollToTop() {
            this.$nextTick(() => {
                const container = document.querySelector('.file-list-container')
                if (container) container.scrollTop = 0
            })
        },
        // 获取日志数据
        getLogs(fileName) {
            this.vueChange = false
            getLogsList(fileName).then((response) => {
                this.logData = response
                this.searchData = this.logData
                this.listSum = this.logData.length
            })
        },

        resetLogs() {
            this.packetsSearch = {
                protocolValue: 'IPv4',
                dataProtocol: 'TCP',
                src: '',
                dst: '',
                srcPort: '',
                dstPort: ''
            }

        },

        // 条件搜索日志数据
        searchLogs() {
            console.log(this.packetsSearch);
            const filteredData = this.logData.filter(packet => {
                const matchProtocol = this.packetsSearch.protocolValue
                    ? packet.protocol === this.packetsSearch.protocolValue
                    : true;

                const matchDataProtocol = this.packetsSearch.dataProtocol
                    ? packet.dataProtocol === this.packetsSearch.dataProtocol
                    : true;

                const matchSrc = this.packetsSearch.src
                    ? packet.ipv4Src === this.packetsSearch.src
                    : true;

                const matchDst = this.packetsSearch.dst
                    ? packet.ipv4Dst === this.packetsSearch.dst
                    : true;

                const matchSrcPort = this.packetsSearch.srcPort
                    ? packet.tcpSrcPort === this.packetsSearch.srcPort
                    : true;

                const matchDstPort = this.packetsSearch.dstPort
                    ? packet.tcpDstPort === this.packetsSearch.dstPort
                    : true;

                return matchProtocol && matchDataProtocol && matchSrc && matchDst && matchSrcPort && matchDstPort;
            });
            this.searchData = filteredData
            console.log(filteredData);
            this.listcurrentPage = 1
            this.listSum = filteredData.length
        },


    },
    mounted() {
        this.getLogsName()
    }
}
</script>
<style scoped>
.log-table {
    border-radius: 8px;
    box-shadow: var(--el-box-shadow-light);
    overflow: hidden;
}

:deep(.log-table .el-table__header th) {
    background-color: #f8f9fa;
    font-weight: 600;
    color: var(--el-text-color-primary);
}

:deep(.log-table .el-table__row) {
    transition: all 0.25s ease;
    cursor: pointer;
}

:deep(.log-table .el-table__row:hover) {
    background-color: #f5f7fa;
    transform: translateX(4px);
}

.file-name-cell {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 0;
}

.file-name-cell .el-icon-document {
    color: var(--el-color-primary);
    font-size: 16px;
}

.file-name-cell .text {
    font-family: Monaco, Consolas, monospace;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
}

/* 优化分页样式 */
:deep(.el-pagination.is-background .el-pager li) {
    border-radius: 4px;
    margin: 0 3px;
}

:deep(.el-pagination.is-background .el-pager li:not(.disabled).active) {
    background-color: var(--el-color-primary);
    color: white;
}

:deep(.el-pagination__total) {
    margin-right: 15px;
}

.search {
    display: flex;
    flex-wrap: wrap;
    /* 允许换行 */
    gap: 10px;
    /* 元素间距统一控制 */
    align-items: center;
    /* 垂直居中 */
    padding: 15px;
    background: #f5f7fa;
    border-radius: 4px;
    margin-bottom: 20px;
}

/* 统一表单元素样式 */
.search .el-select,
.search .el-input {
    flex: 1 1 200px;
    /* 弹性布局+最小宽度 */
    margin: 0 !important;
    /* 清除默认margin */
}

/* 响应式适配 */
@media (max-width: 768px) {

    .search .el-select,
    .search .el-input {
        flex-basis: 150px;
        /* 小屏幕缩小最小宽度 */
    }
}

.top {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>